//反相器
module inv 
(
        A,
        Y
);

input          A;
output         Y;

assign         Y=~A;

endmodule

//testbench
`timescale 1ns/10ps
module inv_tb;
reg aa;
wire yy;
inv inv(
        .A(aa),
        .Y(yy)
);

initial begin
                aa<=0;
        #10     aa<=1;
        #10     aa<=0;
        #10     aa<=1;
        #10     $stop;

end
endmodule

//NAND
module nand_gate (
        A,
        B,
        Y
);
input A;
input B;
output Y;

assign Y=~(A&B);
        
endmodule

//tb

module nand_gate_tb;
reg aa;
reg bb;
wire yy;

nand_gate nand_gate(
        .A(aa),
        .B(bb),
        .Y(yy)
);

initial begin
                aa<=0;bb<=0;
        #10     aa<=1;bb<=0; 
        #10     aa<=0;bb<=1; 
        #10     aa<=1;bb<=1; 
        #10     $stop;

end

        
endmodule

//NAND
module nand_gate_4bit (
        A,
        B,
        Y
);
input[3:0] A;
input[3:0] B;
output[3:0] Y;

assign Y=~(A&B);
        
endmodule

//tb

module nand_gate_4bit_tb;
reg[3:0] aa;
reg[3:0] bb;
wire[3:0] yy;

nand_gate_4bit nand_gate_4bit(
        .A(aa),
        .B(bb),
        .Y(yy)
);

initial begin
                aa<=4'b0000;bb<=4'b1111;
        #10     aa<=4'b1001;bb<=4'b0110; 
        #10     aa<=4'b1010;bb<=4'b1110; 
        #10     aa<=4'b1111;bb<=4'b1001; 
        #10     $stop;

end

        
endmodule

//二选一
module fn_sw_1 (
        a,
        b,
        sel,
        y
);
input a;
input b;
input sel;
output y;

assign y=sel?(a^b):(a&b);//sel=1 y=a^b  sel=0 y=a&b
endmodule

//ifelse always
module fn_sw_if (
        a,
        b,
        sel,
        y
);
input a;
input b;
input sel;
output y;

reg y;
always @(a or b or sel) 
begin
        if (sel==1) begin
                y<=a^b;
        end else begin
                y<=a&b;
        end
        
end
        
endmodule

module fn_sw_if_tb ();
reg aa;
reg bb;
reg ss;
wire yy;
fn_sw_if fn_sw_if(
        .a(aa),
        .b(bb),
        .sel(ss),
        .y(yy)
);
initial begin
                aa<=0;bb<=0;ss<=0;
        #10     aa<=1;bb<=0;ss<=0; 
        #10     aa<=1;bb<=1;ss<=0; 
        #10     aa<=0;bb<=1;ss<=0; 
        #10     aa<=0;bb<=0;ss<=1;
        #10     aa<=1;bb<=0;ss<=1; 
        #10     aa<=1;bb<=1;ss<=1; 
        #10     aa<=0;bb<=1;ss<=1; 
        #10     $stop;
             
end
endmodule

//四选一case
module fn_sw_case (
        a,
        b,
        sel,
        y
);
input a;
input b;
input[1:0] sel;
output y;

reg y;
always @(a or b or sel) 
begin
        case (sel)
                2'b00:begin y<=a&b; end 
                2'b01:begin y<=a|b; end 
                2'b10:begin y<=a^b; end 
                2'b11:begin y<=~(a&b); end 
        endcase        
end        
endmodule
 
//四选一tb
module fn_sw_case_tb ();
reg[3:0] absel;
wire yy;
fn_sw_case fn_sw_case (
        .a(absel[0]),
        .b(absel[1]),
        .sel(absel[3:2]),
        .y(yy)
);     
initial begin
                absel<=0;
        #200    $stop;
end
always begin
        #10 absel<=absel+1;
end
endmodule